
import  os
import glob
from skimage import io, transform, exposure
from skimage.util import img_as_float
###############################################
# 归一化器

class ImageNormalizer:
    """
    图像归一化工具类，提供多种图像归一化方法
    使用scikit-image库进行图像处理
    """
    
    def __init__(self, target_size=None):
        """
        初始化图像归一化器
        
        参数:
            target_size: tuple, 可选，目标图像尺寸 (width, height)
        """
        self.target_size = target_size
    
    def load_image(self, image_path):
        """
        加载图像并转换为浮点型
        
        参数:
            image_path: str, 图像文件路径
            
        返回:
            image: numpy.ndarray, 加载并转换后的图像 (H, W, C) 或 (H, W)
        """
        image = io.imread(image_path)
        # 转换为浮点型，范围[0, 1]
        image = img_as_float(image)
        #print(f"加载后图像形状: {image.shape}")
        
        # 如果指定了目标尺寸，进行图像缩放
        if self.target_size is not None:
            #print(f"原始目标尺寸参数 (宽度, 高度): {self.target_size}")
            # skimage.transform.resize的参数是 (高度, 宽度)
            resize_size = (self.target_size[1], self.target_size[0])
            #print(f"转换后resize尺寸 (高度, 宽度): {resize_size}")
            image = transform.resize(image, resize_size, anti_aliasing=True)
            #print(f"缩放后图像形状: {image.shape}")
        
        return image
    
    def min_max_normalization(self, image, min_val=0.0, max_val=1.0):
        """
        最小-最大归一化
        将图像像素值缩放到指定范围[min_val, max_val]
        
        参数:
            image: numpy.ndarray, 输入图像
            min_val: float, 归一化后的最小值
            max_val: float, 归一化后的最大值
            
        返回:
            normalized_image: numpy.ndarray, 归一化后的图像
        """
        img_min = image.min()
        img_max = image.max()
        
        # 避免除零错误
        if img_max == img_min:
            return np.full_like(image, min_val)
        
        normalized_image = (image - img_min) / (img_max - img_min) * (max_val - min_val) + min_val
        return normalized_image
    
    def mean_std_normalization(self, image, mean=None, std=None):
        """
        均值-标准差归一化
        将图像像素值转换为均值为0，标准差为1的分布
        
        参数:
            image: numpy.ndarray, 输入图像
            mean: float or None, 自定义均值，None则使用图像均值
            std: float or None, 自定义标准差，None则使用图像标准差
            
        返回:
            normalized_image: numpy.ndarray, 归一化后的图像
        """
        if mean is None:
            mean = image.mean()
        if std is None:
            std = image.std()
        
        # 避免除零错误
        if std == 0:
            return np.full_like(image, 0.0)
        
        normalized_image = (image - mean) / std
        return normalized_image
    
    def percentile_normalization(self, image, lower=1, upper=99):
        """
        百分位归一化
        使用百分位裁剪来处理异常值，然后进行最小-最大归一化
        
        参数:
            image: numpy.ndarray, 输入图像
            lower: float, 较低百分位 (0-100)
            upper: float, 较高百分位 (0-100)
            
        返回:
            normalized_image: numpy.ndarray, 归一化后的图像
        """
        # 获取百分位值
        low_val, high_val = np.percentile(image, [lower, upper])
        
        # 裁剪图像
        clipped_image = np.clip(image, low_val, high_val)
        
        # 最小-最大归一化到[0, 1]
        normalized_image = self.min_max_normalization(clipped_image, 0.0, 1.0)
        return normalized_image
    
    def histogram_equalization(self, image):
        """
        直方图均衡化
        增强图像对比度
        
        参数:
            image: numpy.ndarray, 输入图像
            
        返回:
            equalized_image: numpy.ndarray, 均衡化后的图像
        """
        if image.ndim == 3:
            # 彩色图像，对每个通道分别进行均衡化
            equalized_channels = []
            for channel in range(image.shape[2]):
                equalized_channel = exposure.equalize_hist(image[:, :, channel])
                equalized_channels.append(equalized_channel)
            equalized_image = np.stack(equalized_channels, axis=2)
        else:
            # 灰度图像
            equalized_image = exposure.equalize_hist(image)
        
        return equalized_image
    
    def adaptive_histogram_equalization(self, image, clip_limit=0.03, kernel_size=None):
        """
        自适应直方图均衡化
        局部对比度增强
        
        参数:
            image: numpy.ndarray, 输入图像
            clip_limit: float, 裁剪限制，控制对比度增强程度
            kernel_size: tuple or None, 局部区域大小
            
        返回:
            equalized_image: numpy.ndarray, 均衡化后的图像
        """
        if image.ndim == 3:
            # 彩色图像，对每个通道分别进行均衡化
            equalized_channels = []
            for channel in range(image.shape[2]):
                equalized_channel = exposure.equalize_adapthist(
                    image[:, :, channel], clip_limit=clip_limit, kernel_size=kernel_size
                )
                equalized_channels.append(equalized_channel)
            equalized_image = np.stack(equalized_channels, axis=2)
        else:
            # 灰度图像
            equalized_image = exposure.equalize_adapthist(
                image, clip_limit=clip_limit, kernel_size=kernel_size
            )
        
        return equalized_image
    